package main

import (
	"bytes"
	"errors"
	"fmt"
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/widget"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"strings"
	"time"
)

func main() {
	myApp := app.New()
	myApp.Settings().SetTheme(&myTheme{})
	myWindow := myApp.NewWindow("LinkGoYoung")
	myWindow.Resize(fyne.Size{
		Width:  320,
		Height: 480,
	})

	massage := "微信公众号:corehub"
	msg := widget.NewMultiLineEntry()
	msg.SetText(massage)
	label := widget.NewLabel("Welcome！")
	userHard := widget.NewSelect([]string{"!^Iqnd0", "!^Adcm0"}, func(value string) {})

	userHard.SetSelectedIndex(0)
	accountEntry := widget.NewEntry()
	accountEntry.SetPlaceHolder("账号")
	passwordEntry := widget.NewEntry()
	passwordEntry.SetPlaceHolder("密码")

	var user userInfo
	day := time.Now().Day()

	ReadUserInfoJson(label, &user)
	userHard.SetSelected(user.UserHard)
	accountEntry.SetText(user.UserAccount)

	if ReturnPasswd(&user, day) != "" {
		passwordEntry.SetText(ReturnPasswd(&user, day))
	} else if day != 1 {
		passwordEntry.SetText(ReturnPasswd(&user, day-1))
	}

	CheckServer(label, "baidu.com:443")

	form := &widget.Form{
		BaseWidget: widget.BaseWidget{},
		Items: []*widget.FormItem{
			{Text: "账号", Widget: accountEntry}},
		OnSubmit: func() {
			loginURL, userIp, nasIp, userMac := nextUrl("http://www.msftconnecttest.com/redirect")
			massage = "当前网络信息："
			massage += "\nnasip:" + nasIp
			massage += "\nuserip:" + userIp
			massage += "\nusermac:" + userMac
			msg.SetText(massage)
			loginURL = Get(loginURL)
			loginURL = GetBetweenStr(loginURL, "CDATA[", "]]")
			dialog.ShowInformation("登陆……", login(label, loginURL, time.Now().Format("20060102150405"),
				userHard.Selected, accountEntry.Text, passwordEntry.Text), myWindow)
			fmt.Println(label.Text)
			if label.Text == "50：认证成功" && passwordEntry.Text != ReturnPasswd(&user, day-1) {
				user.UserHard = userHard.Selected
				user.UserAccount = accountEntry.Text
				SavePasswd(&user, passwordEntry.Text, time.Now().Day())
				user.LastLoginURL = loginURL
				SaveUserInfoJson(label, &user)
			}
		},
		OnCancel: func() {
			u := user.LastLoginURL
			dialog.ShowInformation("下线……", logout(label, u), myWindow)
		},
		SubmitText: "登录",
		CancelText: "下线",
	}

	form.Append("密码", passwordEntry)

	content := container.New(layout.NewGridLayoutWithColumns(1), msg, container.NewVBox(
		label,
		userHard,
		form,
	))

	myWindow.SetContent(content)
	myWindow.ShowAndRun()
}

func login(label *widget.Label, url, dateTime, userHard, userName, passWord string) string {
	token := "UserName=" + userHard + userName + "&Password=" + passWord + "&AidcAuthAttr1=" + dateTime +
		"&AidcAuthAttr3=keuyGQlK&AidcAuthAttr4=zrDgXllCChyJHjwkcRwhygP0&AidcAuthAttr5=kfe1GQhXdGqOFDtee" +
		"go5zwP9IsNoxX7djTWspPrYm1A%3D%3D&AidcAuthAttr6=5Ia4cQhDfXSFbTtUDGY1yx8%3D&AidcAuthAttr7=6ZWiVl" +
		"wdNiHMXCpOagQv2w2MQs0ohTWJnTu8qK5OibhCydTpTxkI88wadKPWby%2F2PKCVaZUxglbBs96%2FtmLE89M8AJ6y28o7" +
		"qolpFep%2FcYFFRLd7H4MAMrDUMRO0F%2B93jh14fiAZYmtk9hdp%2BZ5w%2BjMQUoV4TCtM9VJ07XQwxlMVg%2F0YKrS1" +
		"s3hXAstdQ1fvdSn3nAVGgdxc%2BJQDrQ%3D%3D&AidcAuthAttr8=jPSyBQxVaXWTQWUaakluj06scJ98nyqCyX7y%2FLU" +
		"k1OkXiNjkXhVGvJhyTuLDaCPhK%2FOFJttlxxiVqNKupnDXkp9%2BR9D9j8p2j5h8FOxoatMaGu0oRdk%3D&createAuthorFlag=0"
	body := POST(url, token, "application/x-www-form-urlencoded")
	ReplyMessage := body
	ReplyMessage = GetBetweenStr(ReplyMessage, "<ReplyMessage>", "</ReplyMessage>")
	label.SetText(ReplyMessage)
	return ReplyMessage
}

func logout(label *widget.Label, url string) string {
	url = "http://58.53.199.144:8001/wispr_logout.jsp?" + strings.Split(url, "?")[1]
	ReplyMessage := Get(url)
	ReplyMessage = GetBetweenStr(ReplyMessage, "<ResponseCode>", "</ResponseCode>")
	if ReplyMessage == "150" {
		label.SetText("150:下线成功")
		return "150:下线成功"
	} else {
		label.SetText("255:下线失败")
		return "255:下线失败"
	}
}

func nextUrl(urlIn string) (urlOut, userIp, nasIp, userMac string) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("请检查网络是否连通", err)
		}
	}()
	req, err := http.NewRequest("GET", urlIn, nil)
	client := new(http.Client)
	client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		return errors.New("redirect")
	}

	var u *url.URL

	response, err := client.Do(req)
	if err != nil {
		if response.StatusCode == http.StatusFound { //status code 302
			u, _ = response.Location()
		} else {
			fmt.Println("未获取到网络信息" + err.Error())
		}
	}
	query := u.Query()
	userIp, nasIp, userMac = query.Get("userip"), query.Get("nasip"), query.Get("usermac")

	urlOut = "http://58.53.199.144:8001/?" + "userip=" + userIp + "&wlanacname=&nasip=" + nasIp + "&usermac=" + userMac + "&aidcauthtype=0"
	return urlOut, userIp, nasIp, userMac
}

func Get(url string) string {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("获取登录链接失败", err)
		}
	}()
	client := &http.Client{}
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Add("User-Agent", "CDMA+WLAN(Mios)")
	resp, _ := client.Do(req)
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			fmt.Println("获取登录链接失败" + err.Error())
		}
	}(resp.Body)
	body, _ := ioutil.ReadAll(resp.Body)
	re := string(body)
	return re
}

func POST(url string, data string, contentType string) string {

	req, _ := http.NewRequest("POST", url, bytes.NewBuffer([]byte(data)))
	req.Header.Add("User-Agent", "CDMA+WLAN(Mios)")
	req.Header.Add("Content-Type", contentType)

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		fmt.Printf("调用接口异常%v", err.Error())
	}
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {

		}
	}(res.Body)
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		fmt.Printf("调用接口异常%v", err.Error())
	}
	return string(body)
}

func GetBetweenStr(str, start, end string) string {
	n := strings.Index(str, start) + len(start)
	if n == -1 {
		n = 0
	}
	str = string([]byte(str)[n:])
	m := strings.Index(str, end)
	if m == -1 {
		m = len(str)
	}
	str = string([]byte(str)[:m])
	return str
}

func CheckServer(label *widget.Label, url string) {
	timeout := 5 * time.Second
	//t1 := time.Now()
	_, err := net.DialTimeout("tcp", url, timeout)
	//massage += "\n网络测试时长 :" + time.Now().Sub(t1).String()

	if err == nil {
		label.SetText("已接入互联网，只能进行下线操作")
		return
	}
	label.SetText("未接入互联网")
	return
}
